package com.pine.dcts;

import com.alibaba.datax.common.element.ColumnCast;
import com.alibaba.datax.common.exception.DataXException;
import com.alibaba.datax.common.statistics.PerfTrace;
import com.alibaba.datax.common.statistics.VMInfo;
import com.alibaba.datax.common.util.Configuration;
import com.alibaba.datax.core.AbstractContainer;
import com.alibaba.datax.core.Engine;
import com.alibaba.datax.core.util.ConfigurationValidate;
import com.alibaba.datax.core.util.FrameworkErrorCode;
import com.alibaba.datax.core.util.container.CoreConstant;
import com.pine.app.module.security.oauth.user.password.BCryptPasswordEncoder;
import com.pine.app.module.security.oauth.user.password.PasswordEncoder;
import com.pine.dcts.common.DctsConstant;
import com.pine.dcts.config.DctsConfig;
import com.pine.dcts.config.DctsConfigParser;
import com.pine.dcts.core.event.JobMessageListener;
import com.pine.dcts.core.event.JobMonitor;
import com.pine.dcts.core.event.JobMonitorEventObject;
import com.pine.dcts.core.job.JobContainer;
import com.pine.dcts.core.job.TaskGroupContainer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;

@Slf4j
public class DctsEngine {

    private static String RUNTIME_MODE;

    public static void main(String[] args) {
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        System.out.println(passwordEncoder.encode("123456"));

    }

    /**
     * datax 启动类
     * 修改源码：1、主要改变他的配置文件内容传递方式，目前直接传递内容进行启动，核心配置常驻处理
     * 2、修改插件处理方式，启动时加载插件包，classloader内存化处理
     *
     * @param json
     */
    public void start(String json) {
        Configuration configuration = DctsConfigParser.parse(json);
        // 如果用户没有明确指定jobid, 则 datax.py 会指定 jobid 默认值为-1
        String jobIdString = configuration.getString(DctsConstant.DATAX_CORE_CONTAINER_JOB_ID);
        if (StringUtils.isEmpty(jobIdString)) {
            throw DataXException.asDataXException(FrameworkErrorCode.CONFIG_ERROR, "必须要在job配置中提供jobId.");
        }
        MDC.put("jobId", jobIdString);
        RUNTIME_MODE = configuration.getString(DctsConstant.DATAX_CORE_CONTAINER_MODEL);

        configuration = configuration.merge(DctsConfig.CONFIGURATION, false);

        long jobId;
//        if (!"-1".equalsIgnoreCase(jobIdString)) {
        jobId = Long.parseLong(jobIdString);
//        } else {
//            // only for dsc & ds & datax 3 update
//            String dscJobUrlPatternString = "/instance/(\\d{1,})/config.xml";
//            String dsJobUrlPatternString = "/inner/job/(\\d{1,})/config";
//            String dsTaskGroupUrlPatternString = "/inner/job/(\\d{1,})/taskGroup/";
//            List<String> patternStringList = Arrays.asList(dscJobUrlPatternString,
//                    dsJobUrlPatternString, dsTaskGroupUrlPatternString);
//            jobId = engine.parseJobIdFromUrl(patternStringList, "");
//        }

        boolean isStandAloneMode = "standalone".equalsIgnoreCase(RUNTIME_MODE);
        if (!isStandAloneMode && jobId == -1) {
            // 如果不是 standalone 模式，那么 jobId 一定不能为-1
            throw DataXException.asDataXException(FrameworkErrorCode.CONFIG_ERROR, "非 standalone 模式必须在 URL 中提供有效的 jobId.");
        }
        configuration.set(CoreConstant.DATAX_CORE_CONTAINER_JOB_ID, jobId);

        //打印vmInfo
        VMInfo vmInfo = VMInfo.getVmInfo();
        if (vmInfo != null) {
            log.info(vmInfo.toString());
        }

        log.info("\n" + Engine.filterJobConfiguration(configuration) + "\n");

        log.debug(configuration.toJSON());
        //此处未做校验
        ConfigurationValidate.doValidate(configuration);
        start(configuration);
        MDC.remove("jobId");
    }

    /* check job model (job/task) first */
    public void start(Configuration allConf) {

        JobMonitorEventObject jobMonitorEventObject = new JobMonitor();
        jobMonitorEventObject.addListener(new JobMessageListener());

        // 绑定column转换信息
        ColumnCast.bind(allConf);

        /**
         * 初始化PluginLoader，可以获取各种插件配置
         */
        /**
         *  去掉此处的绑定 现在从缓存中获取数据
         */
        // LoadUtil.bind(allConf);

        boolean isJob = !("taskGroup".equalsIgnoreCase(allConf
                .getString(DctsConstant.DATAX_CORE_CONTAINER_MODEL)));
        //JobContainer会在schedule后再行进行设置和调整值
        int channelNumber = 0;
        AbstractContainer container;
        long instanceId;
        int taskGroupId = -1;
        if (isJob) {
            allConf.set(CoreConstant.DATAX_CORE_CONTAINER_JOB_MODE, RUNTIME_MODE);
            container = new JobContainer(allConf, jobMonitorEventObject);
            instanceId = allConf.getLong(
                    CoreConstant.DATAX_CORE_CONTAINER_JOB_ID, 0);

        } else {
            container = new TaskGroupContainer(allConf, jobMonitorEventObject);
            instanceId = allConf.getLong(
                    CoreConstant.DATAX_CORE_CONTAINER_JOB_ID);
            taskGroupId = allConf.getInt(
                    CoreConstant.DATAX_CORE_CONTAINER_TASKGROUP_ID);
            channelNumber = allConf.getInt(
                    CoreConstant.DATAX_CORE_CONTAINER_TASKGROUP_CHANNEL);
        }

        //缺省打开perfTrace
        boolean traceEnable = allConf.getBool(CoreConstant.DATAX_CORE_CONTAINER_TRACE_ENABLE, true);
        boolean perfReportEnable = allConf.getBool(CoreConstant.DATAX_CORE_REPORT_DATAX_PERFLOG, true);

        //standlone模式的datax shell任务不进行汇报
        if (instanceId == -1) {
            perfReportEnable = false;
        }

        int priority = 0;
        try {
            priority = Integer.parseInt(System.getenv("SKYNET_PRIORITY"));
        } catch (NumberFormatException e) {
            log.warn("prioriy set to 0, because NumberFormatException, the value is: " + System.getProperty("PROIORY"));
        }

        Configuration jobInfoConfig = allConf.getConfiguration(CoreConstant.DATAX_JOB_JOBINFO);
        //初始化PerfTrace
        PerfTrace perfTrace = PerfTrace.getInstance(isJob, instanceId, taskGroupId, priority, traceEnable);
        perfTrace.setJobInfo(jobInfoConfig, perfReportEnable, channelNumber);
        container.start();
    }


}
